bitkeeper revision 1.1674 (42a2cfb9WFgnh2K4Xr5ev3pSEASVbw)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sun, 5 Jun 2005 10:11:05 +0000 (10:11 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sun, 5 Jun 2005 10:11:05 +0000 (10:11 +0000)
Extend EVTCHNOP_alloc_unbound to allocate a specified port, if
non-zero value is passed in.
Signed-off-by: Keir Fraser <keir@xensource.com>
tools/libxc/xc_evtchn.c
tools/python/xen/lowlevel/xc/xc.c
xen/common/event_channel.c
xen/include/public/event_channel.h

index 9371e61261ae00ce9fb9168a3e740c52b726339c..8ee2fd11ee5b75286aee60e2afe4c8ccfe7127aa 100644 (file)
@@ -39,8 +39,9 @@ int xc_evtchn_alloc_unbound(int xc_handle,
     int         rc;
 
     op.cmd = EVTCHNOP_alloc_unbound;
-    op.u.alloc_unbound.dom = (domid_t)dom;
-   
+    op.u.alloc_unbound.dom  = (domid_t)dom;
+    op.u.alloc_unbound.port = (port != NULL) ? *port : 0;
+
     if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
     {
         if ( port != NULL )
index c23bc461e12eef36af07054cf3e679721c9768fa..9b35ded02a25270704db139206fae5b41808eb1d 100644 (file)
@@ -494,11 +494,12 @@ static PyObject *pyxc_evtchn_alloc_unbound(PyObject *self,
     XcObject *xc = (XcObject *)self;
 
     u32 dom;
-    int port;
+    int port = 0;
 
-    static char *kwd_list[] = { "dom", NULL };
+    static char *kwd_list[] = { "dom", "port", NULL };
 
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
+                                      &dom, &port) )
         return NULL;
 
     if ( xc_evtchn_alloc_unbound(xc->xc_handle, dom, &port) != 0 )
index 75353209f96e1da8f8763f2118c4e5b51b5dd04b..6f6e70766763678bfdde204c9b6fb6b421c82182 100644 (file)
@@ -35,6 +35,8 @@
 #define evtchn_from_port(d,p) \
     (&(bucket_from_port(d,p))[(p)&(EVTCHNS_PER_BUCKET-1)])
 
+#define ERROR_EXIT(_errno) do { rc = (_errno); goto out; } while ( 0 )
+
 static int get_free_port(struct domain *d)
 {
     struct evtchn *chn;
@@ -61,30 +63,48 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
 {
     struct evtchn *chn;
     struct domain *d = current->domain;
-    int            port;
+    int            port = alloc->port;
+    long           rc = 0;
 
     spin_lock(&d->evtchn_lock);
 
-    if ( (port = get_free_port(d)) >= 0 )
+    /* Obtain, or ensure that we already have, a valid <port>. */
+    if ( port == 0 )
     {
-        chn = evtchn_from_port(d, port);
+        if ( (port = get_free_port(d)) < 0 )
+            ERROR_EXIT(port);
+    }
+    else if ( !port_is_valid(d, port) )
+        ERROR_EXIT(-EINVAL);
+    chn = evtchn_from_port(d, port);
+
+    /* Validate channel's current state. */
+    switch ( chn->state )
+    {
+    case ECS_FREE:
         chn->state = ECS_UNBOUND;
         chn->u.unbound.remote_domid = alloc->dom;
+        break;
+
+    case ECS_UNBOUND:
+        if ( chn->u.unbound.remote_domid != alloc->dom )
+            ERROR_EXIT(-EINVAL);
+        break;
+
+    default:
+        ERROR_EXIT(-EINVAL);
     }
 
+ out:
     spin_unlock(&d->evtchn_lock);
 
-    if ( port < 0 )
-        return port;
-
     alloc->port = port;
-    return 0;
+    return rc;
 }
 
 
 static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
 {
-#define ERROR_EXIT(_errno) do { rc = (_errno); goto out; } while ( 0 )
     struct evtchn *chn1, *chn2;
     struct domain *d1, *d2;
     int            port1 = bind->port1, port2 = bind->port2;
@@ -217,7 +237,6 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     bind->port2 = port2;
 
     return rc;
-#undef ERROR_EXIT
 }
 
 
index b00cda66c4b758282fe409cdccb043eee61a264c..e787a0524ac2c973e1a55dab7c2d6e04e0f1898d 100644 (file)
 #define __XEN_PUBLIC_EVENT_CHANNEL_H__
 
 /*
- * EVTCHNOP_alloc_unbound: Allocate a fresh local port and prepare
- * it for binding to <dom>.
+ * EVTCHNOP_alloc_unbound: Prepare a local port for binding to <dom>.
+ * <port> may be wildcarded by setting to zero, in which case a fresh port
+ * will be allocated, and the field filled in on return.
  */
 #define EVTCHNOP_alloc_unbound    6
 typedef struct {
     /* IN parameters */
     domid_t dom;                      /*  0 */
     u16     __pad;
-    /* OUT parameters */
+    /* IN/OUT parameters */
     u32     port;                     /*  4 */
 } PACKED evtchn_alloc_unbound_t; /* 8 bytes */